#include "SubsystemBaseItem.h"
#include "Engine/Vector3.hpp"
#include "Network/Packages/EntityPackage.h"
#include "Managers/EntityManager.h"
#include "Managers/GameManager.h"
#include "Log.h"
#include "Player/PlayerData.h"
#include "GameSingleton.h"
#include <fstream>
#include "Terrain/Terrain.h"
#include "Blocks/ClothingBlock.h"
#include "GameRegistry.hpp"

#include "Components/ComponentPlayer.h"
#include "Components/ComponentMiner.h"
#include "Components/ComponentClothing.h"
#include "Components/ComponentInventory.h"

#include "BaseItemPlugin.h"

using namespace PocketSurvival::Engine;

namespace BaseItem
{
    constexpr int32_t makeClothingValue(int32_t index, int32_t color)
    {
        return Terrain::MakeBlockValue(ClothingBlock::Index(), 0, ClothingBlock::SetClothingIndex(ClothingBlock::SetClothingColor(0, color), index));
    }

    static std::vector<std::vector<int32_t>> basetItemDefaultClothes = {
        { makeClothingValue(32, 0) },
        { makeClothingValue(37, 0), makeClothingValue(1, 9) },
        { makeClothingValue(0, 12) },
        { makeClothingValue(26, 6), makeClothingValue(29, 0) }};

    static std::vector<BaseSlot> baseItemDefaultSlot = {
        BaseSlot(177, 3),
        BaseSlot(29, 1)
    };

    void SubsystemBaseItem::onEntityAdded(entt::entity entity)
    {
        PlayerData **playerDataPtr = GameSingleton::gameRegistry->try_get<PlayerData*>(entity);
        if(playerDataPtr != nullptr)
        {
            PlayerData *playerData = *playerDataPtr;
            if(playerData->isNewCreate == true)
            {
                for(int32_t index = 0; index < m_baseSlots.size(); index++)
                {
                    const BaseSlot& slot = m_baseSlots[index];
                    playerData->componentPlayer->componentInventory->setSlotValue(index, slot.value, slot.count);
                }

                for(int32_t index = 0; index < m_baseClothes.size(); index++)
                {
                    playerData->componentPlayer->componentClothing->setClothes((ClothingSlot)index, m_baseClothes[index]);
                }
            }
        }
    }

    void SubsystemBaseItem::update(float dt){}

    void SubsystemBaseItem::load(const nlohmann::json &json)
    {
        m_gameManager = GameSingleton::singletonPtr->getSingleton<GameManager>();

        std::ifstream stream;
        stream.open(fmt::format("{}/BaseItem.json", BaseItemPlugin::PluginDataDirectory));
        if (stream.is_open())
        {
            nlohmann::json jsonData;
            stream >> jsonData;

            Utils::GetJsonValue<std::vector<std::vector<int32_t>>>(jsonData, m_baseClothes, "Clothes", basetItemDefaultClothes);

            Utils::GetJsonValue<std::vector<BaseSlot>>(jsonData, m_baseSlots, "Slots", baseItemDefaultSlot);
        }
        else
        {
            m_baseClothes = basetItemDefaultClothes;
            m_baseSlots = baseItemDefaultSlot;
        }
        stream.close();


        if(std::filesystem::exists(BaseItemPlugin::PluginDataDirectory) == false)
        {
            if(std::filesystem::create_directories(BaseItemPlugin::PluginDataDirectory) == false)
            {
                throw std::runtime_error("检测不到 基础物品插件 数据文件夹，并且无法创建新的 基础物品插件 数据文件夹");
            }
        }
        nlohmann::json jsonData = {{"Clothes", m_baseClothes},{"Slots", m_baseSlots}};
        Utils::SaveTextFile(fmt::format("{}/BaseItem.json", BaseItemPlugin::PluginDataDirectory), jsonData.dump());
    }

    void SubsystemBaseItem::save(nlohmann::json &json) {}

    void SubsystemBaseItem::saveToMsgJson(nlohmann::json &jsonData) {}

    static const std::string subsystemName = "Players";
    const std::string& SubsystemBaseItem::getName() const
    {
        return subsystemName;
    }

}